package com.oazon.common.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.util.InetAddressUtils;
import org.apache.http.impl.client.DefaultHttpClient;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

import com.oazon.common.Assert;
import com.oazon.common.Logger;
import com.oazon.common.TaskHelper;

/**
 * miscellaneous utilities methods that not belong to all specific utilities
 * classes such as FileUtils/NumberUtils, etc.
 */
public final class Utils {
	private static final String TAG = "Utils";
	private static final int BUFFER_SIZE = 1024 * 16;

	public interface ANDROID_VERSION_CODE {
		int JELLY_BEAN_MR1 = 17; // Android 4.2
		int JELLY_BEAN = 16; // Android 4.1, 4.1.1
		int ICE_CREAM_SANDWICH_MR1 = 15; // Android 4.0.3, 4.0.4
		int ICE_CREAM_SANDWICH = 14; // Android 4.0, 4.0.1, 4.0.2
		int HONEYCOMB_MR2 = 13; // Android 3.2
		int HONEYCOMB_MR1 = 12; // Android 3.1.x
		int HONEYCOMB = 11; // Android 3.0.x
		int GINGERBREAD_MR1 = 10; // Android 2.3.4, Android 2.3.3
		int GINGERBREAD = 9; // Android 2.3.2, Android 2.3.1, Android 2.3
		int FROYO = 8; // Android 2.2.x
		int ECLAIR_MR1 = 7; // Android 2.1.x
		int ECLAIR_0_1 = 6; // Android 2.0.1
		int ECLAIR = 5; // Android 2.0
		int DONUT = 4; // Android 1.6
		int CUPCAKE = 3; // Android 1.5
		int BASE_1_1 = 2; // Android 1.1
		int BASE = 1; // Android 1.0
	}

	private Utils() {
	}

	// this will force import the java package which contains some class
	// eg: forceImportPackage(R.id.class) will force import package
	// com.lenovo.anyshare.R
	public static void forceImportPackage(Class<?> clazz) {
	}

	public static String leftPad(String str, int len, char ch) {
		StringBuilder builder = new StringBuilder();
		int start = str == null ? 0 : str.length();
		for (int i = start; i < len; i++)
			builder.append(ch);
		if (str != null)
			builder.append(str);
		return builder.toString();
	}

	public static String rightPad(String str, int len, char ch) {
		StringBuilder builder = new StringBuilder();
		if (str != null)
			builder.append(str);
		int start = str == null ? 0 : str.length();
		for (int i = start; i < len; i++)
			builder.append(ch);
		return builder.toString();
	}

	public static String toHex(byte value) {
		int unsignedInt = value < 0 ? 256 + value : value;
		return leftPad(Integer.toHexString(unsignedInt), Byte.SIZE / 4, '0');
	}

	public static String toHex(int value) {
		return leftPad(Integer.toHexString(value), Integer.SIZE / 4, '0');
	}

	public static String toHex(long value) {
		return leftPad(Long.toHexString(value), Long.SIZE / 4, '0');
	}

	public static String toHex(byte[] bytes) {
		if (bytes == null)
			return null;

		StringBuilder builder = new StringBuilder();
		for (byte b : bytes)
			builder.append(toHex(b));
		return builder.toString();
	}

	public static String toHex(byte[] bytes, char seperator) {
		Assert.notNull(bytes);
		StringBuilder builder = new StringBuilder();
		for (byte b : bytes)
			builder.append(toHex(b)).append(seperator);
		if (builder.length() > 1)
			builder.deleteCharAt(builder.length() - 1);
		return builder.toString();
	}

	public static boolean isBlank(String string) {
		return string == null || "".equals(string) || "".equals(string.trim());
	}

	public static boolean isNotBlank(String string) {
		return !isBlank(string);
	}

	public static boolean isEmpty(String string) {
		return string == null || "".equals(string);
	}

	public static boolean isNotEmpty(String string) {
		return !isEmpty(string);
	}

	public static void inputStreamToOutputStream(InputStream input,
			OutputStream output) throws IOException {
		byte[] buffer = new byte[BUFFER_SIZE];
		int r;
		while ((r = input.read(buffer)) != -1) {
			output.write(buffer, 0, r);
		}
	}

	// read everything in an input stream and return as string (trim-ed, and may
	// apply optional utf8 conversion)
	public static String inputStreamToString(final InputStream is,
			final boolean sourceIsUTF8) throws IOException {
		InputStreamReader isr = sourceIsUTF8 ? new InputStreamReader(is,
				Charset.forName("UTF-8")) : new InputStreamReader(is);
		BufferedReader br = new BufferedReader(isr);

		StringBuffer sb = new StringBuffer();
		String line;
		while ((line = br.readLine()) != null)
			sb.append(line);
		br.close();
		return sb.toString().trim();
	}

	// url encode a string with UTF-8 encoding
	public static String urlEncode(String src) {
		try {
			return URLEncoder.encode(src, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			Assert.fail(e.getMessage());
			return null;
		}
	}

	public static int readBuffer(InputStream input, byte[] buffer)
			throws IOException {
		return readBuffer(input, buffer, 0, buffer.length);
	}

	/**
	 * inputstream 读取byte[] buffer不能保证一次完整读取，使用本方法可以保证填满buffer
	 * 
	 * @param input
	 * @param buffer
	 * @param offset
	 * @param length
	 * @return
	 * @throws IOException
	 */
	public static int readBuffer(InputStream input, byte[] buffer, int offset,
			int length) throws IOException {
		int sum = 0;
		int r;
		while (length > 0 && (r = input.read(buffer, offset, length)) != -1) {
			sum += r;
			offset += r;
			length -= r;
		}
		return sum;
	}

	public static synchronized LinkedList<String> getIps() {
		LinkedList<String> ipList = new LinkedList<String>();
		try {
			for (Enumeration<NetworkInterface> en = NetworkInterface
					.getNetworkInterfaces(); en.hasMoreElements();) {
				NetworkInterface intf = en.nextElement();

				for (Enumeration<InetAddress> enumIpAddr = intf
						.getInetAddresses(); enumIpAddr.hasMoreElements();) {
					InetAddress inetAddress = enumIpAddr.nextElement();
					if (inetAddress instanceof Inet6Address)
						continue;

					if (!inetAddress.isLoopbackAddress()
							&& !inetAddress.isMCGlobal()
							&& !inetAddress.isAnyLocalAddress()) {
						String addr = inetAddress.getHostAddress();
						ipList.add(addr);
					}
				}
			}

			if (ipList.size() == 0)
				return null;
			return ipList;
		} catch (SocketException ex) {
			return null;
		}
	}

	public static String getLocalIp() {
		String hostname = null;
		try {
			Enumeration<NetworkInterface> enu = NetworkInterface
					.getNetworkInterfaces();
			while (enu.hasMoreElements()) {
				NetworkInterface networkInterface = enu.nextElement();
				String network = networkInterface.getName();
				Enumeration<InetAddress> addressEnu = networkInterface
						.getInetAddresses();
				while (addressEnu.hasMoreElements()) {
					InetAddress address = addressEnu.nextElement();
					if (InetAddressUtils
							.isIPv4Address(address.getHostAddress())
							&& !address.isLinkLocalAddress()
							&& !address.isLoopbackAddress()) {
						if (network.toLowerCase().contains("wlan")) {
							return address.getHostAddress();
						} else {
							hostname = address.getHostAddress();
						}
					}
				}
			}
		} catch (SocketException e) {
			Logger.w(TAG, "get local ip failed: " + e.getMessage());
		}

		return hostname;
	}

	public static long max(long value1, long value2) {
		return (value1 > value2 ? value1 : value2);
	}

	public static String getSimCountryIso(Context ctx) {
		try {
			TelephonyManager telManager = (TelephonyManager) ctx
					.getSystemService(Context.TELEPHONY_SERVICE);
			return telManager.getSimCountryIso() + "";
		} catch (Exception e) {
			return "";
		}
	}

	public static String getNetworkTypeName(Context ctx) {
		try {
			ConnectivityManager cm = (ConnectivityManager) ctx
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo info = cm.getActiveNetworkInfo();
			return info.getTypeName(); // cmwap/cmnet/wifi/uniwap/uninet
		} catch (Exception e) {
			return null;
		}
	}

	public static int getNetworkType(Context ctx) {
		try {
			ConnectivityManager cm = (ConnectivityManager) ctx
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo info = cm.getActiveNetworkInfo();
			return info.getType();
		} catch (Exception e) {
			return -1;
		}
	}

	public static String getWifiInfoMacAddress(Context ctx) {
		try {
			WifiManager wifi = (WifiManager) ctx
					.getSystemService(Context.WIFI_SERVICE);
			WifiInfo info = wifi.getConnectionInfo();
			return info.getMacAddress();
		} catch (Exception e) {
			return null;
		}
	}

	public static String getWifiInfoBSSID(Context ctx) {
		try {
			WifiManager wm = (WifiManager) ctx
					.getSystemService(Context.WIFI_SERVICE);
			WifiInfo info = wm.getConnectionInfo();
			return info.getBSSID();
		} catch (Exception e) {
			return null;
		}
	}

	public static String getAppVersion(Context ctx) {
		try {
			PackageInfo info = ctx.getPackageManager().getPackageInfo(
					ctx.getPackageName(), PackageManager.GET_CONFIGURATIONS);
			return info.versionName + "-" + info.versionCode;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static boolean hasInstallShortCut(Context context, String name) {
		boolean result = false;
		Cursor cursor = null;
		try {
			String url = "";
			if (android.os.Build.VERSION.SDK_INT < 8) {
				url = "content://com.android.launcher.settings/favorites?notify=true";
			} else {
				url = "content://com.android.launcher2.settings/favorites?notify=true";
			}
			ContentResolver resolver = context.getContentResolver();
			cursor = resolver.query(Uri.parse(url), null, "title=?",
					new String[] { name }, null);
			result = cursor != null && cursor.moveToFirst();
		} finally {
			close(cursor);
		}

		return result;
	}

	/**
	 * install a activity shortcut. Don't check whether it is installed.
	 * 
	 * @param context
	 *            application context object
	 * @param Intent
	 *            shortcut's intent.
	 * @param nameResId
	 *            shortcut's display name's resource id
	 * @param iconResId
	 *            shortcut's display icon's resource id
	 */
	public static void doInstallShortcut(Context context, Intent intent,
			int nameResId, int iconResId) {
		Intent shortcut = new Intent(
				"com.android.launcher.action.INSTALL_SHORTCUT");
		shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME,
				context.getString(nameResId));
		shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
		ShortcutIconResource iconRes = Intent.ShortcutIconResource.fromContext(
				context, iconResId);
		shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes);
		shortcut.putExtra("duplicate", false);
		context.sendBroadcast(shortcut);
	}

	public static int toInt(byte b) {
		return b & 0xFF;
	}

	public static byte[] toBytes(long value) {
		byte[] result = new byte[Long.SIZE / Byte.SIZE];
		for (int i = 0; i < result.length; i++) {
			result[i] = (byte) value;
			value >>= Byte.SIZE;
		}
		return result;
	}

	public static byte[] toBytes(int value) {
		byte[] result = new byte[Integer.SIZE / Byte.SIZE];
		for (int i = 0; i < result.length; i++) {
			result[i] = (byte) value;
			value >>= Byte.SIZE;
		}
		return result;
	}

	public static int toInt(byte[] buffer, int start) {
		int result = 0;
		int end = Math.min(buffer.length, start + (Integer.SIZE / Byte.SIZE));
		int moved = 0;
		for (int i = start; i < end; i++) {
			result |= (buffer[i] & 0xFF) << moved;
			moved += Byte.SIZE;
		}
		return result;
	}

	public static boolean isInt(String value) {
		try {
			Integer.valueOf(value);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static boolean isEquals(Object obj1, Object obj2) {
		boolean isNull01 = obj1 == null;
		boolean isNull02 = obj2 == null;

		if (isNull01 ^ isNull02)
			return false;
		if (isNull01 && isNull02)
			return true;
		return obj1.equals(obj2);
	}

	/**
	 * close cursor, catch and ignore all exceptions.
	 * 
	 * @param cursor
	 *            the cursor object, may be null
	 */
	public static void close(Cursor cursor) {
		if (cursor != null) {
			try {
				cursor.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * close input stream, catch and ignore all exceptions.
	 * 
	 * @param stream
	 *            the input stream object, may be null
	 */
	public static void close(InputStream stream) {
		if (stream != null) {
			try {
				stream.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * close output stream, catch and ignore all exceptions.
	 * 
	 * @param stream
	 *            the output stream object, may be null
	 */
	public static void close(OutputStream stream) {
		if (stream != null) {
			try {
				stream.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * close reader, catch and ignore all exceptions.
	 * 
	 * @param reader
	 *            the reader object, may be null
	 */
	public static void close(Reader reader) {
		if (reader != null) {
			try {
				reader.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * close writer, catch and ignore all exceptions.
	 * 
	 * @param writer
	 *            the writer object, may be null
	 */
	public static void close(Writer writer) {
		if (writer != null) {
			try {
				writer.close();
			} catch (Exception e) {
			}
		}
	}

	public static void close(RandomAccessFile raf) {
		if (raf != null) {
			try {
				raf.close();
			} catch (IOException e) {
			}
		}
	}

	public enum DEVICETYPE {
		DEVICE_PHONE("phone"), DEVICE_PAD("pad");

		private String mValue;

		DEVICETYPE(String value) {
			mValue = value;
		}

		private final static Map<String, DEVICETYPE> VALUES = new HashMap<String, DEVICETYPE>();
		static {
			for (DEVICETYPE item : DEVICETYPE.values())
				VALUES.put(item.mValue, item);
		}

		@SuppressLint("DefaultLocale")
		public static DEVICETYPE fromString(String value) {
			return VALUES.get(value.toLowerCase());
		}

		@Override
		public String toString() {
			return mValue;
		}
	}

	public static DEVICETYPE detectDeviceType(Context ctx) {
		double screenSize = 0D;
		try {
			DisplayMetrics displaymetrics = ctx.getApplicationContext()
					.getResources().getDisplayMetrics();
			float width = displaymetrics.widthPixels;
			float height = displaymetrics.heightPixels;
			float xdpi = displaymetrics.densityDpi > displaymetrics.xdpi ? displaymetrics.densityDpi
					: displaymetrics.xdpi;
			float ydpi = displaymetrics.densityDpi > displaymetrics.ydpi ? displaymetrics.densityDpi
					: displaymetrics.ydpi;
			float inchW = width / xdpi;
			float inchH = height / ydpi;
			screenSize = Math.sqrt(Math.pow(inchW, 2D) + Math.pow(inchH, 2D));
		} catch (Exception exception) {
			return DEVICETYPE.DEVICE_PHONE;
		}
		if (screenSize >= 6.5D) // some device has 6" screen, such as K7 mini
			return DEVICETYPE.DEVICE_PAD;

		return DEVICETYPE.DEVICE_PHONE;
	}

	public static int getScreenWidth(Context ctx) {
		DisplayMetrics displaymetrics = ctx.getApplicationContext()
				.getResources().getDisplayMetrics();
		return displaymetrics.widthPixels;
	}

	public static int getScreenHeight(Context ctx) {
		DisplayMetrics displaymetrics = ctx.getApplicationContext()
				.getResources().getDisplayMetrics();
		return displaymetrics.heightPixels;
	}

	public static float getDensity(Context ctx) {
		return ctx.getResources().getDisplayMetrics().density;
	}

	public static String getChannel(Context context) {
		try {
			String pn = context.getPackageName();
			PackageManager pm = context.getPackageManager();
			ApplicationInfo info = pm.getApplicationInfo(pn,
					PackageManager.GET_META_DATA);
			return info.metaData.getString("lenovo:channel");
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}

		return null;
	}

	public static int getVersionCode(Context context) {
		String pn = context.getPackageName();
		PackageManager pm = context.getPackageManager();
		try {
			return pm.getPackageInfo(pn, 0).versionCode;
		} catch (NameNotFoundException e) {
			return 0;
		}
	}

	public static String getVersionName(Context context, String packageName) {
		PackageManager pm = context.getPackageManager();
		try {
			return pm.getPackageInfo(packageName, 0).versionName;
		} catch (NameNotFoundException e) {
			return "unknown";
		}
	}

	public static boolean isDevVersion(Context context) {
		boolean ret = true;

		try {
			String pn = context.getPackageName();
			PackageManager pm = context.getPackageManager();
			PackageInfo pi = pm.getPackageInfo(pn, 0);
			ret = (pi.versionCode == 1);
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}

		return ret;
	}

	public static boolean isSimReady(Context context) {
		TelephonyManager tm = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		return tm.getSimState() == TelephonyManager.SIM_STATE_READY;
	}

	public static boolean isSupportPhone(Context context) {
		TelephonyManager tm = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		return tm.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE;
	}

	public static boolean isBeforeDate(int year, int month, int day) {
		Calendar deadline = Calendar.getInstance();
		deadline.set(year, month - 1, day, 0, 0, 0);
		Calendar now = Calendar.getInstance();
		return now.before(deadline);
	}

	public static boolean isBeforeTime(int year, int month, int day, int hour,
			int minute, int second) {
		Calendar deadline = Calendar.getInstance();
		deadline.set(year, month - 1, day, hour, minute, second);
		Calendar now = Calendar.getInstance();
		return now.before(deadline);
	}

	public static boolean isAfterDate(int year, int month, int day) {
		Calendar deadline = Calendar.getInstance();
		deadline.set(year, month - 1, day, 0, 0, 0);
		Calendar now = Calendar.getInstance();
		return now.after(deadline);
	}

	public static boolean isAfterTime(int year, int month, int day, int hour,
			int minute, int second) {
		Calendar deadline = Calendar.getInstance();
		deadline.set(year, month - 1, day, hour, minute, second);
		Calendar now = Calendar.getInstance();
		return now.after(deadline);
	}

	public interface IntenetCallback {
		void onConnected(boolean connected);
	};

	public static void checkIntenetStatus(final IntenetCallback callback) {
		TaskHelper.execZForSDK(new TaskHelper.Task() {

			@Override
			public void execute() throws Exception {
				boolean connected = false;

				try {
					HttpClient httpclient = new DefaultHttpClient();
					HttpGet request = new HttpGet("http://www.lenovo.com");
					HttpResponse response = httpclient.execute(request);

					int code = response.getStatusLine().getStatusCode();
					if (code == 200)
						connected = true;
				} catch (ClientProtocolException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}

				callback.onConnected(connected);
			}

			@Override
			public void callback(Exception e) {
				// empty
			}
		});
	}

	// Check current network whether is connected
	// first element mean whether mobile is connected, second element mean
	// whether wifi is connected
	public static Pair<Boolean, Boolean> checkConnected(Context context) {
		boolean isMobileConnected = false;
		boolean isWifiConnected = false;

		ConnectivityManager connectMgr = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connectMgr == null)
			return null;

		NetworkInfo mobNetInfo = connectMgr
				.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
		NetworkInfo wifiNetInfo = connectMgr
				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		// getNetworkInfo may return null if the device does not support the
		// network type
		// e.g. some pad do not support Mobile data connection
		if (mobNetInfo != null)
			isMobileConnected = mobNetInfo.isConnected();
		if (wifiNetInfo != null)
			isWifiConnected = wifiNetInfo.isConnected();

		return new Pair<Boolean, Boolean>(isMobileConnected, isWifiConnected);
	}

	public static Boolean isWifiConnected(Context context) {
		if (context == null) {
			return false;
		}
		Object object = context.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (object == null) {
			return false;
		}
		ConnectivityManager connectMgr = (ConnectivityManager) object;
		Assert.notNull(connectMgr);

		NetworkInfo wifiNetInfo = connectMgr
				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		Assert.notNull(wifiNetInfo);
		return wifiNetInfo.isConnected();
	}

	public static boolean isWifiConnectedOrConnecting(Context context) {
		ConnectivityManager connManager = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		Assert.notNull(connManager);

		NetworkInfo wifi = connManager
				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		Assert.notNull(wifi);

		return wifi.isConnectedOrConnecting();
	}

	public static boolean isAppRunning(Context context, String packageName) {
		if (packageName == null)
			return false;

		ActivityManager am = (ActivityManager) context
				.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningTaskInfo> list = am.getRunningTasks(100);
		for (RunningTaskInfo info : list) {
			if (info.topActivity.getPackageName().equals(packageName)
					|| info.baseActivity.getPackageName().equals(packageName)) {
				return true;
			}
		}

		return false;
	}

	public static final String CONFIG_FILE = "show_first";
	public static final long SPLASH_DISPLAY_LENGHT = 10 * 1000;

	/**
	 * 閸掓稑缂撻惄顔肩秿
	 * 
	 * @param path
	 */
	public static void createDirs(File path) {
		if (path != null && !path.exists()) {
			path.mkdirs();
		}
	}

	/**
	 * 閺傚洣娆㈤弰顖氭儊鐎涙ê婀�
	 * 
	 * @param file
	 * @return
	 */
	public static boolean isFileExist(File file) {
		if (file != null && file.exists()) {
			return true;
		}
		return false;
	}

	/**
	 * 閺嶈宓侀幍瀣簚閸掑棜椴搁悳鍥︾矤dp鏉烆剚鍨歱x
	 * 
	 * @param context
	 * @param dpValue
	 * @return
	 */
	public static int dip2px(Context context, float dpValue) {
		final float scale = context.getResources().getDisplayMetrics().density;

		return (int) (dpValue * scale + 0.5f);
	}

	/**
	 * 閺嶈宓侀幍瀣簚閻ㄥ嫬鍨庢潏銊у芳閿燂拷px(閸嶅繒绀�) 閻ㄥ嫬宕熼敓锟芥潪顒佸灇閿燂拷dp
	 */
	public static int px2dip(Context context, float pxValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (pxValue / scale + 0.5f) - 15;
	}

	/**
	 * 鐏忓敀x閸婅壈娴嗛幑顤嶈礋sp閸婄》绱濇穱婵婄槈閺傚洤鐡ф径褍鐨稉宥呭綁
	 * 
	 * @param pxValue
	 * @param fontScale閿涘湒isplayMetrics缁
	 *            鑵戠仦鐑囨嫹 ?scaledDensity閿燂拷
	 * @return
	 */
	public static int px2sp(float pxValue, float fontScale) {
		return (int) (pxValue / fontScale + 0.5f);
	}

	/**
	 * 鐏忓敄p閸婅壈娴嗛幑顤嶈礋px閸婄》绱濇穱婵婄槈閺傚洤鐡ф径褍鐨稉宥呭綁
	 * 
	 * @param spValue
	 * @param fontScale閿涘湒isplayMetrics缁
	 *            鑵戠仦鐑囨嫹 ?scaledDensity閿燂拷
	 * @return
	 */
	public static int sp2px(float spValue, float fontScale) {
		return (int) (spValue * fontScale + 0.5f);
	}

	/**
	 * 閿燂拷閿熸枻鎷穝dcard閺勵垰鎯侀崣顖滄暏
	 * 
	 * @return true娑撳搫褰查悽顭掔礉閸氾箑鍨稉杞扮瑝閸欘垳鏁�
	 */
	public static boolean sdCardIsAvailable() {
		String status = Environment.getExternalStorageState();
		if (!status.equals(Environment.MEDIA_MOUNTED))
			return false;
		return true;
	}

	/**
	 * 妤犲矁鐦夐幍瀣簚閸欓攱鐗稿蹇旀Ц閸氾附顒滈敓锟�
	 * 
	 * @param mobileNumber
	 * @return
	 */
	public static boolean validateMobileNumber(String mobileNumber) {
		if (matchingText("^(13[0-9]|15[0-9]|18[7|8|9|6|5])\\d{4,8}$",
				mobileNumber)) {
			return true;
		}
		return false;
	}

	/**
	 * 妤犲矁鐦夌�涙顑侀敓锟介弰顖氭儊闁倸鎮庨弻鎰瀸閺嶇厧绱�
	 * 
	 * @param expression
	 *            濮濓絽鍨悰銊ㄦ彧閿燂拷
	 * @param text
	 *            閹垮秳缍旈惃鍕摟缁楋缚瑕�
	 * @return
	 */
	private static boolean matchingText(String expression, String text) {
		Pattern p = Pattern.compile(expression); // 濮濓絽鍨悰銊ㄦ彧閿燂拷
		Matcher m = p.matcher(text); // 閹垮秳缍旈惃鍕摟缁楋缚瑕�
		boolean b = m.matches();
		return b;
	}

	/**
	 * 閿燂拷閿熸枻鎷风純鎴犵捕閻樿鎷�?
	 */
	public static boolean hasNetwork(Context context) {
		android.net.ConnectivityManager cManager = (android.net.ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		android.net.NetworkInfo info = cManager.getActiveNetworkInfo();
		if (info != null && info.isAvailable()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 閿燂拷閿熸枻鎷风純鎴犵捕閻樿鎷�?2
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isNetworkAvailable(Context context) {
		android.net.ConnectivityManager connectivity = (android.net.ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE); // 閼惧嘲褰囩化鑽ょ埠缂冩垹绮舵潻鐐村复缁狅紕鎮婇敓锟�
		if (connectivity == null) { // 婵″倹鐏夌純鎴犵捕缁狅紕鎮婇崳銊よ礋null
			return false; // 鏉╂柨娲杅alse鐞涖劍妲戠純鎴犵捕閺冪姵纭舵潻鐐村复
		} else {
			android.net.NetworkInfo[] info = connectivity.getAllNetworkInfo(); // 閼惧嘲褰囬敓锟介敓鏂ゆ嫹閻ㄥ嫮缍夌紒婊嗙箾閹恒儱顕敓锟�
			if (info != null) { // 缂冩垹绮舵穱鈩冧紖娑撳秳璐焠ull閿燂拷
				for (int i = 0; i < info.length; i++) { // 闁秴宸荤純鎴ｇ熅鏉╃偞甯寸�电钖�
					if (info[i].isConnected()) { // 瑜版挻婀侀敓锟介敓鏂ゆ嫹缂冩垹绮舵潻鐐村复鐎电钖勬潻鐐村复娑撳﹦缍夌紒婊勬
						return true; // 鏉╂柨娲杢rue鐞涖劍妲戠純鎴犵捕鏉╃偞甯村锝呯埗
					}
				}
			}
		}
		return false;
	}

	public static boolean isMobileNetworkAvailable(Context context) {
		// 閼惧嘲褰囨惔鏃傛暏娑撳﹣绗呴敓锟�
		ConnectivityManager connectivityManager = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		// 閼惧嘲褰囩化鑽ょ埠閻ㄥ嫯绻涢幒銉︽箛閿燂拷
		NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
		// 閼惧嘲褰囩純鎴犵捕閻ㄥ嫯绻涢幒銉﹀剰閿燂拷
		if (activeNetInfo != null
				&& activeNetInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
			// 閸掋倖鏌�3G閿燂拷
			return true;
		}
		return false;
	}

	/**
	 * 閻楀牊婀伴敓锟�
	 * 
	 * @param context
	 * @return
	 */
	public static String getVersionName(Context context) {
		try {
			ApplicationInfo appInfo = context.getPackageManager()
					.getApplicationInfo(context.getPackageName(),
							PackageManager.GET_META_DATA);
			String name = appInfo.metaData.getString("version_name");
			if (name != null) {
				return name;
			}
			return context.getPackageManager().getPackageInfo(
					context.getPackageName(), 0).versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 濞撶娀浜鹃敓锟�
	 * 
	 * @param context
	 * @param metaName
	 * @return
	 */
	public static int getChannel(Context context, String metaName) {
		try {
			ApplicationInfo appInfo = context.getPackageManager()
					.getApplicationInfo(context.getPackageName(),
							PackageManager.GET_META_DATA);
			return appInfo.metaData.getInt(metaName);

		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return -1;
	}

	/**
	 * 鐎涙顑佹稉鑼舵祮閹存亼nt
	 * 
	 * @param str
	 * @return
	 */
	public static int parseStr2Int(String str) {
		if (str == null) {
			return -1;
		}
		try {
			return Integer.parseInt(str);
		} catch (NumberFormatException e) {
			return -1;
		}
	}

	/**
	 * 鐎涙顑佹稉鑼舵祮閹存亼nt
	 * 
	 * @param str
	 * @return
	 */
	public static float parseStr2Float(String str) {
		if (str == null) {
			return -1;
		}
		try {
			return Float.parseFloat(str);
		} catch (NumberFormatException e) {
			return -1;
		}
	}

	/**
	 * 閸掋倖鏌囩�涙顑佹稉鍙夋Ц閸氾附妲搁崥鍫熺《閿燂拷6鏉╂稑鍩楅敓锟�
	 * 
	 * @author: Xue Wenchao
	 * @param str
	 * @return
	 * @return: boolean
	 * @date: 2014-1-21 娑撳﹤宕�10:13:23
	 */
	public static boolean isHexString(String str) {
		if (str == null) {
			return false;
		}
		return Pattern.matches("^[0-9a-fA-F]++$", str);
	}

	/**
	 * 鐎涙顑佹稉鑼舵祮閹存�ng
	 * 
	 * @param str
	 * @return
	 */
	public static long parseStr2Long(String str) {
		if (str == null) {
			return -1;
		}
		try {
			return Long.parseLong(str);
		} catch (NumberFormatException e) {
			return -1;
		}
	}

	/**
	 * 闂呮劘妫屾潏鎾冲弳闁款喚娲�
	 * 
	 * @param view
	 * @param context
	 */
	public static void hideSoftInput(EditText view, Context context) {
		InputMethodManager inputMeMana = (InputMethodManager) context
				.getSystemService(Context.INPUT_METHOD_SERVICE);
		inputMeMana.hideSoftInputFromWindow(view.getWindowToken(),
				InputMethodManager.HIDE_NOT_ALWAYS);
	}

	/**
	 * 閺勫墽銇氭潪顖炴暛閿燂拷
	 */
	public static void showSoftInput(Context context) {
		InputMethodManager inputMeMana = (InputMethodManager) context
				.getSystemService(Context.INPUT_METHOD_SERVICE);
		inputMeMana.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT,
				InputMethodManager.HIDE_NOT_ALWAYS);
	}

	/**
	 * 鐠侊紕鐣荤�涙顑佹稉顏呮殶閿涘奔绔存稉顏呯溄鐎涙鐣绘稉銈勯嚋
	 * 
	 * @param s
	 * @return
	 */
	public static int countWord(String s) {
		if (s == null || s.length() == 0) {
			return 0;
		}
		int n = s.length(), a = 0, b = 0;
		int len = 0;
		char c;
		for (int i = 0; i < n; i++) {
			c = s.charAt(i);
			if (Character.isSpaceChar(c)) {
				++b;
			} else if (isAscii(c)) {
				++a;
			} else {
				++len;
			}
		}
		return len + (int) Math.ceil((a + b) / 2.0);
	}

	public static boolean isAscii(char c) {
		return c <= 0x7f;
	}

	/**
	 * 妤犲矁鐦夐柇顔绢唸閸︽澘娼冮弰顖氭儊閸氬牊纭�
	 * 
	 * @param email
	 * @return
	 */
	public static boolean checkEmail(String email) {
		boolean flag = false;
		try {
			String check = "^[a-zA-Z][\\w\\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\\w\\.-]*[a-zA-Z0-9]\\.[a-zA-Z][a-zA-Z\\.]*[a-zA-Z]$";
			Pattern regex = Pattern.compile(check);
			Matcher matcher = regex.matcher(email);
			flag = matcher.matches();
		} catch (Exception e) {
			flag = false;
		}

		return flag;
	}

	/**
	 * 鏉╁洦鎶ら弬鍥ㄦ拱娑擃厾娈慼tml閼存碍婀版穱鈩冧紖
	 * 
	 * @param inputString
	 * @return
	 */
	public static String Html2Text(String inputString) {
		String htmlStr = inputString; // 閸氱帴tml閺嶅洨顒烽惃鍕摟缁楋缚瑕�
		String textStr = "";
		java.util.regex.Pattern p_script;
		java.util.regex.Matcher m_script;
		java.util.regex.Pattern p_style;
		java.util.regex.Matcher m_style;
		java.util.regex.Pattern p_html;
		java.util.regex.Matcher m_html;
		java.util.regex.Pattern p_html1;
		java.util.regex.Matcher m_html1;
		try {
			String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; // 鐎规矮绠焥cript閻ㄥ嫭顒滈崚娆掋�冩潏鎯х础{閿燂拷script[^>]*?>[\\s\\S]*?<\\/script>
			String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 鐎规矮绠焥tyle閻ㄥ嫭顒滈崚娆掋�冩潏鎯х础{閿燂拷style[^>]*?>[\\s\\S]*?<\\/style>
			String regEx_html = "<[^>]+>"; // 鐎规矮绠烪TML閺嶅洨顒烽惃鍕劀閸掓瑨銆冩潏鎯х础
			String regEx_html1 = "<[^>]+";
			p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
			m_script = p_script.matcher(htmlStr);
			htmlStr = m_script.replaceAll(""); // 鏉╁洦鎶cript閺嶅洨顒�

			p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
			m_style = p_style.matcher(htmlStr);
			htmlStr = m_style.replaceAll(""); // 鏉╁洦鎶tyle閺嶅洨顒�

			p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
			m_html = p_html.matcher(htmlStr);
			htmlStr = m_html.replaceAll(""); // 鏉╁洦鎶tml閺嶅洨顒�

			p_html1 = Pattern.compile(regEx_html1, Pattern.CASE_INSENSITIVE);
			m_html1 = p_html1.matcher(htmlStr);
			htmlStr = m_html1.replaceAll(""); // 鏉╁洦鎶tml閺嶅洨顒�

			textStr = htmlStr;

		} catch (Exception e) {
			System.err.println("Html2Text: " + e.getMessage());
		}

		return textStr;// 鏉╂柨娲栭弬鍥ㄦ拱鐎涙顑侀敓锟�
	}

	/**
	 * 閸愭瑥娴橀悧鍥у煂SD閿燂拷
	 * 
	 * @param bitmap
	 * @param filename
	 * @param url
	 * @throws IOException
	 */
	public static void saveBitmap(Bitmap bitmap, String filePath) {
		File file = new File(filePath);
		FileOutputStream out;
		try {
			out = new FileOutputStream(file);
			if (bitmap.compress(Bitmap.CompressFormat.JPEG, 70, out)) {
				out.flush();
				out.close();
			}
		} catch (FileNotFoundException e) {

		} catch (IOException e) {

		}
	}

	/**
	 * 娴犲海缍夌紒婊�绗呮潪钘夋禈閻楀洤鑻熸穱婵嗙摠閸掔増瀵氱�规俺鐭鹃敓锟�
	 * 
	 * @param imgUrl
	 * @param filePath
	 */
	public static void downloadImageAndSave(String imgUrl, String filePath) {
		URL url;
		InputStream is = null;
		FileOutputStream fos = null;
		URLConnection conn;
		try {
			url = new URL(imgUrl);
			conn = url.openConnection();
			is = conn.getInputStream();
			fos = new FileOutputStream(new File(filePath));
			Utils.copyStream(is, fos);
		} catch (Exception e) {

		} finally {
			try {
				is.close();
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 閹风柉绀夐敓锟�
	 * 
	 * @param is
	 * @param os
	 */
	public static void copyStream(InputStream is, OutputStream os)
			throws IOException {
		if (is == null || os == null) {
			return;
		}
		BufferedInputStream bufIs;
		boolean shouldClose = false;
		if (is instanceof BufferedInputStream) {
			bufIs = (BufferedInputStream) is;
		} else {
			bufIs = new BufferedInputStream(is);
			shouldClose = true;
		}

		int bufLen = 102400;
		byte[] buf = new byte[bufLen];
		int len;
		while (true) {
			len = bufIs.read(buf);
			if (len < 0) {
				break;
			}
			os.write(buf, 0, len);
		}
		if (shouldClose) {
			bufIs.close();
		}
	}

	/**
	 * 瀵版鍩岀仦蹇撶鐎硅棄瀹�
	 * 
	 * @param context
	 * @return
	 */
	public static int getWinWidth(Activity context) {
		// TODO Auto-generated constructor stub
		return context.getWindowManager().getDefaultDisplay().getWidth();
	}

	/**
	 * 瀵版鍩岀仦蹇撶妤傛ê瀹�
	 * 
	 * @param context
	 * @return
	 */
	public static int getWinHight(Activity context) {
		// TODO Auto-generated constructor stub
		return context.getWindowManager().getDefaultDisplay().getHeight();
	}

	public static int calculateCharLength(String src) {
		int counter = -1;
		if (src != null) {
			counter = 0;
			final int len = src.length();
			for (int i = 0; i < len; i++) {
				char sigleItem = src.charAt(i);
				if (isAlphanumeric(sigleItem)) {
					counter++;
				} else if (Character.isLetter(sigleItem)) {
					counter = counter + 2;
				} else {
					counter++;
				}
			}
		} else {
			counter = -1;
		}

		return counter;
	}

	/**
	 * 閸掋倖鏌囩�涙顑侀弰顖氭儊娑撻缚瀚抽弬鍥х摟濮ｅ秵鍨ㄩ懓鍛存▼閹峰闆嗛弫鏉跨摟.
	 * 
	 * @param ch
	 *            char鐎涙顑�
	 * @return true or false
	 */
	public static boolean isAlphanumeric(char ch) {
		// 鐢悂鍣虹�规矮绠�
		final int DIGITAL_ZERO = 0;
		final int DIGITAL_NINE = 9;
		final char MIN_LOWERCASE = 'a';
		final char MAX_LOWERCASE = 'z';
		final char MIN_UPPERCASE = 'A';
		final char MAX_UPPERCASE = 'Z';

		if ((ch >= DIGITAL_ZERO && ch <= DIGITAL_NINE)
				|| (ch >= MIN_LOWERCASE && ch <= MAX_LOWERCASE)
				|| (ch >= MIN_UPPERCASE && ch <= MAX_UPPERCASE)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * decode js閻⑩暋scape缂傛牜鐖滈惃鍕摟缁楋缚瑕�
	 * 
	 * @method: unEscape
	 * @description: TODO
	 * @author: DongFuhai
	 * @param src
	 * @return
	 * @return: String
	 * @date: 2013-10-14 娑撳宕�5:57:56
	 */
	public static String unEscape(String src) {
		StringBuffer tmp = new StringBuffer();
		tmp.ensureCapacity(src.length());
		int lastPos = 0, pos = 0;
		char ch;
		while (lastPos < src.length()) {
			pos = src.indexOf("%", lastPos);
			if (pos == lastPos) {
				if (src.charAt(pos + 1) == 'u') {
					ch = (char) Integer.parseInt(
							src.substring(pos + 2, pos + 6), 16);
					tmp.append(ch);
					lastPos = pos + 6;
				} else {
					ch = (char) Integer.parseInt(
							src.substring(pos + 1, pos + 3), 16);
					tmp.append(ch);
					lastPos = pos + 3;
				}
			} else {
				if (pos == -1) {
					tmp.append(src.substring(lastPos));
					lastPos = src.length();
				} else {
					tmp.append(src.substring(lastPos, pos));
					lastPos = pos;
				}
			}
		}
		return tmp.toString();
	}

	// 鏈�杩戝洜涓洪」鐩渶瑕侊紝涓嶈app鍦ㄥ簲鐢ㄥ垪琛ㄦ樉绀猴紝鍙兘鐢ㄨ嚜宸辩殑鍚姩鍣ㄥ惎鍔�
	// 鍩烘湰鎼炲畾锛屾晥鏋滃疄鐜颁簡锛屼笉杩囦笌鎴戠殑璁″垝鐩稿樊鎸鸿繙鐨�. &nbsp;&nbsp;
	public static void RunApp(String packageName, Context context) {
		PackageInfo pi;
		try {
			pi = context.getPackageManager().getPackageInfo(packageName, 0);
			Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
			// resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
			resolveIntent.setPackage(pi.packageName);
			PackageManager pManager = context.getPackageManager();
			List<ResolveInfo> apps = pManager.queryIntentActivities(
					resolveIntent, 0);

			ResolveInfo ri = apps.iterator().next();
			if (ri != null) {
				packageName = ri.activityInfo.packageName;
				String className = ri.activityInfo.name;

				Intent intent = new Intent(Intent.ACTION_MAIN);
				// intent.addCategory(Intent.CATEGORY_LAUNCHER);

				ComponentName cn = new ComponentName(packageName, className);

				intent.setComponent(cn);
				context.startActivity(intent);
			}
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}

	}

	public static int getFontHeight(float fontSize) {
		Paint paint = new Paint();
		paint.setTextSize(fontSize);
		FontMetrics fm = paint.getFontMetrics();
		return (int) Math.ceil(fm.descent - fm.ascent);
	}
	

	public static boolean isO2(String provider){
		if(provider == null || "".equals(provider) || "o2".equals(provider) ||"moco".equals(provider)){
			return true;
		}
		return false;
	}
	
	public static String fixImageUrlSize(String url){
		String tempUrl = null;
		if(url != null){
			tempUrl = url.replace("80y80", "210y210");
		}
		return tempUrl;
	}
}
